package fifis.game;

import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.scene.Node;
import fifis.game.common.Common;
import fifis.mvc.controller.FController;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import org.apache.log4j.Logger;

/**
 * This class sets the logic engine of the game
 * 
 * @author porfiriopartida
 */
public abstract class FLogic implements Runnable, PhysicsCollisionListener {
    final static protected Logger log4j = Logger.getLogger(FLogic.class);

//    ArrayList<FController> actors = new ArrayList<FController>();
    HashMap<Integer, FController> actors = new HashMap<Integer, FController>();
    ArrayList<FController> entities = new ArrayList<FController>();
    FController scenario;

    public FController getScenario() {
        return scenario;
    }

//    public void setScenario(FController scenario) {
//        this.scenario = scenario;
//    }
    public Node getSky() {
        return sky;
    }

    public void setSky(String skyName) {
        if (this.sky != null) {
            Common.getInstance().getRootNode().detachChild(this.sky);
        }
        this.sky = Common.getInstance().getNode("Scenes/Sky/" + skyName + ".j3o", skyName, true);
        Common.getInstance().getRootNode().attachChild(this.sky);
    }
    Node sky;

    public void removeActor(int id) {
        FController actor = actors.get(id);
        actors.remove(id);
        actor.getNode().removeFromParent();
//        Common.getInstance().getRootNode().detachChild(actor.getNode());
    }

    public void setScenario(FController scenario) {
        if (this.scenario != null) {
            Common.getInstance().getRootNode().detachChild(this.scenario.getNode());
        }
        this.scenario = scenario;
        Common.getInstance().getRootNode().attachChild(scenario.getNode());
    }

    public final void updateActors() {
        Collection<FController> actorsList = actors.values();
        for (FController actor : actorsList) {
            try {
                actor.update();
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
        updateEntities();
        update();
    }

    public final void updateEntities() {
        for (FController entity : entities) {
            try {
                entity.update();
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }

    public abstract void update();

    public synchronized void addActor(int id, FController actor) {
//        actors.add(actor);
        actors.put(id, actor);
        addActor(actor.getNode());
    }

    public FController getActor(int id) {
        return actors.get(id);
    }

    public void addEntity(FController entity) {
//        actors.add(actor);
        entities.add(entity);
//        actors.put(id, actor);
        addActor(entity.getNode());
    }

    public void removeEntity(FController entity) {
        entities.remove(entity);
        Common.getInstance().getRootNode().detachChild(entity.getNode());
    }

    public void addEntitie(Node entity) {
        scenario.getNode().attachChild(entity);
    }

    public void addActor(Node actor) {
        scenario.getNode().attachChild(actor);
    }

//    public ArrayList<FController> getActors() {
//        return actors;
//    }
    public Collection<FController> getActors() {
        return actors.values();
    }
//    public void setActors(ArrayList<FController> actors) {
//        this.actors = actors;
//    }

    public void clearActors() {
        this.actors.clear();
        Collection<FController> actorsList = actors.values();
        for (FController actor : actorsList) {
            Common.getInstance().getRootNode().detachChildNamed(actor.getName());
        }
    }
}
